﻿using Cobra11Undercover.Terrain;
using Engine.Camera;
using Engine.FileFormats3D;
using Engine.Graphics;
using Scenario_Editor;
using Scenario_Editor.AddinManager;
using Scenario_Editor.Tools;
using System;
using System.ComponentModel.Composition;
using System.IO;
using System.Windows.Forms;

namespace Cobra11Undercover
{
    [ExportMetadata("Name", "C11 Undercover Scenery Editor Addin")]
    [ExportMetadata("Version", 1)]
    [Export(typeof(Scenario_Editor.AddinManager.IAddinScenarioEditor))]
    internal class GameDllScenarioEditor : Scenario_Editor.AddinManager.IAddinScenarioEditor
    {
        #region Private Fields

        private ToolStripButton toolStripButton_VertexColor;

        #endregion Private Fields



        #region Private Fields

        private Engine.Engine _engine;
        private TerrainPaintingControl _terrainPaintingControl;

        #endregion Private Fields

        #region Public Constructors

        [ImportingConstructor]
        public GameDllScenarioEditor([Import("MainEngine")]Engine.Engine engine)
        {
            this._engine = engine;

            this._terrainPaintingControl = new TerrainPaintingControl();
            //this._materialEditControl = new List<Material.MaterialEditUI>();
            //this.configurationDialog = new Configuration.WR2ConfigurationDialog();
            //this.terrainToolstrip = new Toolstrips.TerrainToolstrip();
        }

        #endregion Public Constructors

        #region Public Properties

        public IExporter Exporter
        {
            get
            {
                throw new NotImplementedException();
            }

            set
            {
                throw new NotImplementedException();
            }
        }

        public MaterialManager MaterialManager { get; private set; }
        public ITerrain Terrain { get; private set; }

        public ITerrainPaintingControl TerrainPaintingControl
        {
            get
            {
                return this._terrainPaintingControl;
            }
        }

        #endregion Public Properties

        #region Public Methods

        public void AutomaticTextureing(ITerrain terrain)
        {
            throw new NotImplementedException();
        }

        public void ExportScenario(ScenarioFile scenarioFile)
        {
            SyneticStandards.Configuration.WorldRacing2ConfigurationData wr2Configuration = new SyneticStandards.Configuration.WorldRacing2ConfigurationData();

            DirectoryInfo projectDirectory = new DirectoryInfo(@"D:\Games\Alarm für Cobra 11 - Undercover\Scenarios\MyOwn");
            bool exportObjects = true;

            if (exportObjects)
            {
                exportObjects = true;
                scenarioFile.DynObjectManager.CopyObjectsToFolder(projectDirectory.FullName);
                scenarioFile.ObjectManager.SceneryObjectManager.CopyObjectsToFolder(projectDirectory.FullName);
                scenarioFile.RoadManager.SceneryObjectManager.CopyObjectsToFolder(projectDirectory.FullName);
            }

            Mesh3dData[] meshes = new Mesh3dData[scenarioFile.Terrain.nSectorsX * scenarioFile.Terrain.nSectorsY];

            for (int y = 0; y < scenarioFile.Terrain.nSectorsY; y++)
            {
                for (int x = 0; x < scenarioFile.Terrain.nSectorsX; x++)
                {
                    meshes[x + y * scenarioFile.Terrain.nSectorsX] = new Mesh3dData(scenarioFile.MaterialManager,
                        scenarioFile.Terrain.GetTerrainMesh(x, y), scenarioFile.MaterialManager.Engine.addinManager, scenarioFile.MaterialManager.Engine.addinManager.CurrentAddin);
                }
            }

            var scenario = C11UndercoverScenery.CreateNewScenery(projectDirectory.FullName, wr2Configuration.GroundsFile.GetGrounds(), wr2Configuration.TextureToMaterialFile.TextureProperties, meshes, scenarioFile.Terrain.nSectorsY, scenarioFile.Terrain.nSectorsX, this._engine);

            if (exportObjects)
            {
                scenario.QadFile.ResetObjects();
                scenario.QadFile.AddNewObjects(scenarioFile.DynObjectManager, wr2Configuration.SceneryObjectPropertiesFile);
                scenario.QadFile.AddNewObjects(scenarioFile.ObjectManager.SceneryObjectManager, wr2Configuration.SceneryObjectPropertiesFile);
                scenario.QadFile.AddNewObjects(scenarioFile.RoadManager.SceneryObjectManager, wr2Configuration.SceneryObjectPropertiesFile);
                scenario.QadFile.UpdateBlockinfosForObjects();
            }
            bool exportTracks = true;
            bool createIdealLine = false;
            if (exportTracks)
            {
                try
                {
                    for (int i = 0; i < scenarioFile.TrackManager.Tracks.Count; i++)
                    {
                        if (false)
                        {
                            // Export LWO-File
                            string filename = projectDirectory.FullName + "\\track_" + ((int)(i + 1)).ToString() + ".lwo";

                            try
                            {
                                scenarioFile.TrackManager.Tracks[i].ExportToLWO(filename, 0.10f);
                                //   this.richTextBox.AppendText("\nSaved to LWO file: \"" + filename + "\"\n");
                            }
                            catch
                            {
                                //  this.richTextBox.AppendText(string.Format("\nError while writing Track_{0}", i));
                            }
                        }
                        else
                        {
                            //loopState.
                            string filename = projectDirectory.FullName + "\\V1\\Tracks\\" + projectDirectory.Name + "_" + ((int)(i + 1)).ToString().PadLeft(2, '0') + ".trk";
                            scenarioFile.TrackManager.Tracks[i].ExportToWr2Track(filename, (ITerrain)scenarioFile.Terrain, createIdealLine);

                            // Application.DoEvents();
                            //  AppendTextToLog("\nTrack Saved: \"" + filename + "\"" /*+ ((float)sw.Elapsed.TotalSeconds).ToString() */+ "\n");
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error track writing...");
                }
            }
            scenario.Save(projectDirectory.FullName);
            MessageBox.Show("Export Complete!");
        }

        public string GetGameName()
        {
            return Cobra11Undercover.GameDll.gameName;
        }

        public IMaterialEditorControl GetNewMaterialEditControl()
        {
            Material.MaterialEditControl materialEditControl = new Material.MaterialEditControl();
            materialEditControl.SetMaterialManager(this.MaterialManager);

            return materialEditControl;
        }

        public ToolStripButton[] GetToolstripbuttonRendermodes()
        {
            this.toolStripButton_VertexColor = new System.Windows.Forms.ToolStripButton();

            //
            // toolStripButton_VertexColor
            //
            this.toolStripButton_VertexColor.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
            this.toolStripButton_VertexColor.Image = Properties.Resources.VertexColor;
            this.toolStripButton_VertexColor.ImageTransparentColor = System.Drawing.Color.Magenta;
            this.toolStripButton_VertexColor.Name = "toolStripButton_VertexColor";
            this.toolStripButton_VertexColor.Size = new System.Drawing.Size(36, 36);
            this.toolStripButton_VertexColor.Text = "Shows the VertexColor";
            this.toolStripButton_VertexColor.Click += new System.EventHandler(OnChangeShaderToVertexColor);

            ToolStripButton[] buttons = new ToolStripButton[]
                {
                    this.toolStripButton_VertexColor
                };

            return buttons;
        }

        public ToolStripMenuItem GetToolstripitems()
        {
            MessageBox.Show("No Toolstripbuttons for c11 addin yet.");
            ToolStripMenuItem toolStripMenuItem = new ToolStripMenuItem("C11 Undercover");
            return toolStripMenuItem;
        }

        public void ImportTexturesFromGame(string sceneryEditorTextureFolder)
        {
            throw new NotImplementedException();
        }

        public ISceneryExtractor LoadScenery(Engine.Engine engine, ShaderManager shaderManager, Camera camera)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            string folder = @"C:\Dev\Stadium";
            folder = @"D:\Games\Alarm für Cobra 11 - Undercover\Scenarios\Alpen";
            fbd.SelectedPath = folder;
            this._engine = engine;
            if (fbd.ShowDialog() == DialogResult.OK)
            {
                folder = fbd.SelectedPath;
                try
                {
                    //string folder = @"D:\Games\Alarm für Cobra 11 - Undercover\Scenarios\Stadium";
                    C11UndercoverScenery scenario = new C11UndercoverScenery(this._engine, shaderManager, folder, engine.Camera, 50000.0f);
                    return scenario;
                }
                catch (Exception ex)
                {
                    throw new Exception("Canßt load C11 Undercover Scenery:\n" + ex.Message);
                }
            }
            return null;
        }

        public void OnMaterialMangerChanged(object materialManager, EventArgs eventArgs)
        {
            this.MaterialManager = (Engine.Graphics.MaterialManager)materialManager;
            this._terrainPaintingControl.MaterialManagerChanged(this.MaterialManager, null);
        }

        public void OnTerrainChanged(object sender, EventArgs e)
        {
            this.Terrain = (Scenario_Editor.Tools.ITerrain)sender;
        }

        public IGameVertex PaintVertex(IGameVertex originalVertexData, IGameVertex newVertexData)
        {
            throw new NotImplementedException();
        }

        private void OnChangeShaderToVertexColor(object sender, EventArgs e)
        {
            GameDll.shaderArray.GlobalShader = Shaders.EnumGlobalShader.VertexColor;
        }

        #endregion Public Methods
    }
}